﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using Microsoft.Kinect;
using System.Windows.Forms;

namespace KinectSkeletonViewer3
{
    /// <summary>
    /// MainWindow.xaml 的交互逻辑
    /// </summary>
    public partial class MainWindow : Window
    {
        KinectSensor kinect;
        private byte[] pixelData;
        private Skeleton[] skeletons;
      //  Point P;
        private readonly Brush[] skeletonBrushes;//绘图笔刷
        public MainWindow()
        {
            InitializeComponent();
        }

        private void Window_Loaded(object sender, RoutedEventArgs e)
        {
            kinect = (from sensor in KinectSensor.KinectSensors
                      where sensor.Status ==
                          KinectStatus.Connected
                      select sensor).FirstOrDefault();
            kinect.ColorStream.Enable(ColorImageFormat.RgbResolution640x480Fps30);
            kinect.SkeletonStream.Enable();
            kinect.Start();
            kinect.ColorFrameReady += new EventHandler<ColorImageFrameReadyEventArgs>(kinect_ColorFrameReady);
            kinect.SkeletonFrameReady += new EventHandler<SkeletonFrameReadyEventArgs>(kinect_SkeletonFrameReady);

        }

        void kinect_SkeletonFrameReady(object sender, SkeletonFrameReadyEventArgs e)
        {
            //throw new NotImplementedException();
            bool isSkeletonDataReady = false;
            using (SkeletonFrame skeletonFrame = e.OpenSkeletonFrame())
            {
                if (skeletonFrame != null)
                {
                    skeletons = new Skeleton[skeletonFrame.SkeletonArrayLength];
                    skeletonFrame.CopySkeletonDataTo(skeletons);
                    isSkeletonDataReady = true;
                }
            }
            if (isSkeletonDataReady)
            {
                Skeleton currentSkeleton = (from s in skeletons
                                            where s.TrackingState ==
                                                SkeletonTrackingState.Tracked
                                            select s).FirstOrDefault();

                if (currentSkeleton != null)
                {
                    Polyline headPolyline = new Polyline();
                    Polyline handleftPolyline = new Polyline();
                    Polyline handrightPolyline = new Polyline();
                    Polyline footleftPolyline = new Polyline();
                    Polyline footrightPolyline = new Polyline();

                    LayoutRoot.Children.Clear();
                    headPolyline.Points.Clear();
                    handleftPolyline.Points.Clear();
                    handrightPolyline.Points.Clear();
                    footleftPolyline.Points.Clear();
                    footrightPolyline.Points.Clear();

                    Joint head = currentSkeleton.Joints[JointType.Head];
                    Joint shouldercenter = currentSkeleton.Joints[JointType.ShoulderCenter];
                    Joint shoulderleft = currentSkeleton.Joints[JointType.ShoulderLeft];
                    Joint shoulderright = currentSkeleton.Joints[JointType.ShoulderRight];
                    Joint elbowleft = currentSkeleton.Joints[JointType.ElbowLeft];
                    Joint elbowright = currentSkeleton.Joints[JointType.ElbowRight];
                    Joint wristleft = currentSkeleton.Joints[JointType.WristLeft];
                    Joint wristright = currentSkeleton.Joints[JointType.WristRight];
                    Joint handleft = currentSkeleton.Joints[JointType.HandLeft];
                    Joint handright = currentSkeleton.Joints[JointType.HandRight];
                    Joint spine = currentSkeleton.Joints[JointType.Spine];
                    Joint hipcenter = currentSkeleton.Joints[JointType.HipCenter];
                    Joint hipleft = currentSkeleton.Joints[JointType.HipLeft];
                    Joint hipright = currentSkeleton.Joints[JointType.HipRight];
                    Joint kneeleft = currentSkeleton.Joints[JointType.KneeLeft];
                    Joint kneeright = currentSkeleton.Joints[JointType.KneeRight];
                    Joint ankleleft = currentSkeleton.Joints[JointType.AnkleLeft];
                    Joint ankleright = currentSkeleton.Joints[JointType.AnkleRight];
                    Joint footleft = currentSkeleton.Joints[JointType.FootLeft];
                    Joint footright = currentSkeleton.Joints[JointType.FootRight];

                    headPolyline.Points.Add(lockWithRedSpot(head, headPoint));
                    setpointPosition(headPoint, lockWithRedSpot(head, headPoint));

                    setpointPosition(shouldercenterPoint, lockWithRedSpot(shouldercenter, shouldercenterPoint));
                    headPolyline.Points.Add(lockWithRedSpot(shouldercenter, shouldercenterPoint));                    
                    handleftPolyline.Points.Add(lockWithRedSpot(shouldercenter,shouldercenterPoint));                
                    handrightPolyline.Points.Add(lockWithRedSpot(shouldercenter, shouldercenterPoint));

                    setpointPosition(shoulderleftPoint, lockWithRedSpot(shoulderleft, shoulderleftPoint));
                    handleftPolyline.Points.Add(lockWithRedSpot(shoulderleft, shoulderleftPoint));

                    setpointPosition(shoulderrightPoint, lockWithRedSpot(shoulderright, shoulderrightPoint));
                    handrightPolyline.Points.Add(lockWithRedSpot(shoulderright, shoulderrightPoint));

                    setpointPosition(elbowleftPoint, lockWithRedSpot(elbowleft, elbowleftPoint));
                    handleftPolyline.Points.Add(lockWithRedSpot(elbowleft,elbowleftPoint));

                    setpointPosition(elbowrightPoint, lockWithRedSpot(elbowright, elbowrightPoint));
                    handrightPolyline.Points.Add(lockWithRedSpot(elbowright, elbowrightPoint));

                    setpointPosition(wristleftPoint, lockWithRedSpot(wristleft, wristleftPoint));
                    handleftPolyline.Points.Add(lockWithRedSpot(wristleft, wristleftPoint));

                    setpointPosition(wristrightPoint, lockWithRedSpot(wristright, wristrightPoint));
                    handrightPolyline.Points.Add(lockWithRedSpot(wristright, wristrightPoint));

                    setpointPosition(handleftPoint, lockWithRedSpot(handleft, handleftPoint));
                    handleftPolyline.Points.Add(lockWithRedSpot(handleft, handleftPoint));

                    setpointPosition(handrightPoint, lockWithRedSpot(handright, handrightPoint));
                    handrightPolyline.Points.Add(lockWithRedSpot(handright, handrightPoint));

                    setpointPosition(spinePoint, lockWithRedSpot(spine, spinePoint));
                    headPolyline.Points.Add(lockWithRedSpot(spine, spinePoint));
                    
                    setpointPosition(hipcenterPoint, lockWithRedSpot(hipcenter, hipcenterPoint));
                    headPolyline.Points.Add(lockWithRedSpot(hipcenter, hipcenterPoint));
                    footleftPolyline.Points.Add(lockWithRedSpot(hipcenter, hipcenterPoint));
                    footrightPolyline.Points.Add(lockWithRedSpot(hipcenter, hipcenterPoint));

                    setpointPosition(hipleftPoint, lockWithRedSpot(hipleft, hipleftPoint));
                    footleftPolyline.Points.Add(lockWithRedSpot(hipleft, hipleftPoint));

                    setpointPosition(hiprightPoint, lockWithRedSpot(hipright, hiprightPoint));
                    footrightPolyline.Points.Add(lockWithRedSpot(hipright, hiprightPoint));
                 
                    setpointPosition(kneeleftPoint, lockWithRedSpot(kneeleft, kneeleftPoint));
                    footleftPolyline.Points.Add(lockWithRedSpot(kneeleft, kneeleftPoint));
                 
                    setpointPosition(kneerightPoint, lockWithRedSpot(kneeright, kneerightPoint));
                    footrightPolyline.Points.Add(lockWithRedSpot(kneeright, kneerightPoint));
                
                    setpointPosition(ankleleftPoint, lockWithRedSpot(ankleleft, ankleleftPoint));
                    footleftPolyline.Points.Add(lockWithRedSpot(ankleleft, ankleleftPoint));
               
                    setpointPosition(anklerightPoint, lockWithRedSpot(ankleright, anklerightPoint));
                    footrightPolyline.Points.Add(lockWithRedSpot(ankleright, anklerightPoint));
                  
                    setpointPosition(footleftPoint, lockWithRedSpot(footleft, footleftPoint));
                    footleftPolyline.Points.Add(lockWithRedSpot(footleft, footleftPoint));
              
                    setpointPosition(footrightPoint, lockWithRedSpot(footright, footrightPoint));
                    footrightPolyline.Points.Add(lockWithRedSpot(footright, footrightPoint));

                    headPolyline.Stroke = new SolidColorBrush(Colors.Blue);
                    headPolyline.StrokeThickness = 5;
                    LayoutRoot.Children.Add(headPolyline);

                    handleftPolyline.Stroke = new SolidColorBrush(Colors.Blue);
                    handleftPolyline.StrokeThickness = 5;
                    LayoutRoot.Children.Add(handleftPolyline);

                    handrightPolyline.Stroke = new SolidColorBrush(Colors.Blue);
                    handrightPolyline.StrokeThickness = 5;
                    LayoutRoot.Children.Add(handrightPolyline);

                    footleftPolyline.Stroke = new SolidColorBrush(Colors.Blue);
                    footleftPolyline.StrokeThickness = 5;
                    LayoutRoot.Children.Add(footleftPolyline);

                    footrightPolyline.Stroke = new SolidColorBrush(Colors.Blue);
                    footrightPolyline.StrokeThickness = 5;
                    LayoutRoot.Children.Add(footrightPolyline);

                    ProcessGersture(head, handleft, handright);
                }
            }
        }


        Point lockWithRedSpot(Joint s , FrameworkElement j)
        {
            
            ColorImagePoint colorPoint = kinect.MapSkeletonPointToColor(s.Position, kinect.ColorStream.Format);
            Point P = new Point((int)(ColorImage.Width * colorPoint.X / kinect.ColorStream.FrameWidth),
                (int)(ColorImage.Height * colorPoint.Y / kinect.ColorStream.FrameHeight));        
            return P;
        }
        private void setpointPosition(FrameworkElement ellipse, Point p)
        {
            Canvas.SetLeft(ellipse, p.X);
            Canvas.SetTop(ellipse, p.Y);
            LayoutRoot.Children.Add(ellipse);
        }

        private void ProcessGersture(Joint head, Joint lefthand, Joint righthand)
        {
            bool isBackGestureActive = false;
            bool isForwardGestureActive = false;

            if (righthand.Position.X > head.Position.X + 0.45)
            {
                if (!isBackGestureActive && !isForwardGestureActive)
                {
                    isForwardGestureActive = true;
                    System.Windows.Forms.SendKeys.SendWait("{Right}");
                }
            }
            else
            {
                isForwardGestureActive = false;
            }
            if (lefthand.Position.X < head.Position.X - 0.45)
            {
                if (!isForwardGestureActive && !isBackGestureActive)
                {
                    isBackGestureActive = true;
                    System.Windows.Forms.SendKeys.SendWait("{Left}");
                }
            }
            else
            {
                isBackGestureActive = false;
            }
        }



        void kinect_ColorFrameReady(object sender, ColorImageFrameReadyEventArgs e)
        {
            // throw new NotImplementedException();
            using (ColorImageFrame imageFrame = e.OpenColorImageFrame())
            {
                if (imageFrame != null)
                {
                    this.pixelData = new byte[imageFrame.PixelDataLength];
                    imageFrame.CopyPixelDataTo(this.pixelData);
                    this.ColorImage.Source = BitmapSource.Create(imageFrame.Width, imageFrame.Height,
                        96, 96, PixelFormats.Bgr32, null, pixelData, imageFrame.Width * imageFrame.BytesPerPixel);
                }
            }
        }

    }
}
